home *** CD-ROM | disk | FTP | other *** search
- #! /usr/local/bin/python
-
- # Scan MH folder, display results in window
-
- import os
- import sys
- import regex
- import getopt
- import string
- import mhlib
-
- from Tkinter import *
-
- from dialog import dialog
-
- mailbox = os.environ['HOME'] + '/Mail'
-
- def main():
- global root, tk, top, mid, bot
- global folderbox, foldermenu, scanbox, scanmenu, viewer
- global folder, seq
- global mh, mhf
-
- # Parse command line options
-
- folder = 'inbox'
- seq = 'all'
- try:
- opts, args = getopt.getopt(sys.argv[1:], '')
- except getopt.error, msg:
- print msg
- sys.exit(2)
- for arg in args:
- if arg[:1] == '+':
- folder = arg[1:]
- else:
- seq = arg
-
- # Initialize MH
-
- mh = mhlib.MH()
- mhf = mh.openfolder(folder)
-
- # Build widget hierarchy
-
- root = Tk()
- tk = root.tk
-
- top = Frame(root)
- top.pack({'expand': 1, 'fill': 'both'})
-
- # Build right part: folder list
-
- right = Frame(top)
- right.pack({'fill': 'y', 'side': 'right'})
-
- folderbar = Scrollbar(right, {'relief': 'sunken', 'bd': 2})
- folderbar.pack({'fill': 'y', 'side': 'right'})
-
- folderbox = Listbox(right, {'exportselection': 0})
- folderbox.pack({'expand': 1, 'fill': 'both', 'side': 'left'})
-
- foldermenu = Menu(root)
- foldermenu.add('command',
- {'label': 'Open Folder',
- 'command': open_folder})
- foldermenu.add('separator')
- foldermenu.add('command',
- {'label': 'Quit',
- 'command': 'exit'})
- foldermenu.bind('<ButtonRelease-3>', folder_unpost)
-
- folderbox['yscrollcommand'] = (folderbar, 'set')
- folderbar['command'] = (folderbox, 'yview')
- folderbox.bind('<Double-1>', open_folder, 1)
- folderbox.bind('<3>', folder_post)
-
- # Build left part: scan list
-
- left = Frame(top)
- left.pack({'expand': 1, 'fill': 'both', 'side': 'left'})
-
- scanbar = Scrollbar(left, {'relief': 'sunken', 'bd': 2})
- scanbar.pack({'fill': 'y', 'side': 'right'})
-
- scanbox = Listbox(left, {'font': 'fixed'})
- scanbox.pack({'expand': 1, 'fill': 'both', 'side': 'left'})
-
- scanmenu = Menu(root)
- scanmenu.add('command',
- {'label': 'Open Message',
- 'command': open_message})
- scanmenu.add('command',
- {'label': 'Remove Message',
- 'command': remove_message})
- scanmenu.add('command',
- {'label': 'Refile Message',
- 'command': refile_message})
- scanmenu.add('separator')
- scanmenu.add('command',
- {'label': 'Quit',
- 'command': 'exit'})
- scanmenu.bind('<ButtonRelease-3>', scan_unpost)
-
- scanbox['yscrollcommand'] = (scanbar, 'set')
- scanbar['command'] = (scanbox, 'yview')
- scanbox.bind('<Double-1>', open_message)
- scanbox.bind('<3>', scan_post)
-
- # Separator between middle and bottom part
-
- rule2 = Frame(root, {'bg': 'black'})
- rule2.pack({'fill': 'x'})
-
- # Build bottom part: current message
-
- bot = Frame(root)
- bot.pack({'expand': 1, 'fill': 'both'})
- #
- viewer = None
-
- # Window manager commands
-
- root.minsize(800, 1) # Make window resizable
-
- # Fill folderbox with text
-
- setfolders()
-
- # Fill scanbox with text
-
- rescan()
-
- # Enter mainloop
-
- root.mainloop()
-
- def folder_post(e):
- x, y = e.x_root, e.y_root
- foldermenu.post(x - 10, y - 10)
- foldermenu.grab_set()
-
- def folder_unpost(e):
- tk.call('update', 'idletasks')
- foldermenu.grab_release()
- foldermenu.unpost()
- foldermenu.invoke('active')
-
- def scan_post(e):
- x, y = e.x_root, e.y_root
- scanmenu.post(x - 10, y - 10)
- scanmenu.grab_set()
-
- def scan_unpost(e):
- tk.call('update', 'idletasks')
- scanmenu.grab_release()
- scanmenu.unpost()
- scanmenu.invoke('active')
-
- scanparser = regex.compile('^ *\([0-9]+\)')
-
- def open_folder(e=None):
- global folder, mhf
- sel = folderbox.curselection()
- if len(sel) != 1:
- if len(sel) > 1:
- msg = "Please open one folder at a time"
- else:
- msg = "Please select a folder to open"
- dialog(root, "Can't Open Folder", msg, "", 0, "OK")
- return
- i = sel[0]
- folder = folderbox.get(i)
- mhf = mh.openfolder(folder)
- rescan()
-
- def open_message(e=None):
- global viewer
- sel = scanbox.curselection()
- if len(sel) != 1:
- if len(sel) > 1:
- msg = "Please open one message at a time"
- else:
- msg = "Please select a message to open"
- dialog(root, "Can't Open Message", msg, "", 0, "OK")
- return
- cursor = scanbox['cursor']
- scanbox['cursor'] = 'watch'
- tk.call('update', 'idletasks')
- i = sel[0]
- line = scanbox.get(i)
- if scanparser.match(line) >= 0:
- num = string.atoi(scanparser.group(1))
- m = mhf.openmessage(num)
- if viewer: viewer.destroy()
- from MimeViewer import MimeViewer
- viewer = MimeViewer(bot, '+%s/%d' % (folder, num), m)
- viewer.pack()
- viewer.show()
- scanbox['cursor'] = cursor
-
- def interestingheader(header):
- return header != 'received'
-
- def remove_message(e=None):
- itop = scanbox.nearest(0)
- sel = scanbox.curselection()
- if not sel:
- dialog(root, "No Message To Remove",
- "Please select a message to remove", "", 0, "OK")
- return
- todo = []
- for i in sel:
- line = scanbox.get(i)
- if scanparser.match(line) >= 0:
- todo.append(string.atoi(scanparser.group(1)))
- mhf.removemessages(todo)
- rescan()
- fixfocus(min(todo), itop)
-
- lastrefile = ''
- tofolder = None
- def refile_message(e=None):
- global lastrefile, tofolder
- itop = scanbox.nearest(0)
- sel = scanbox.curselection()
- if not sel:
- dialog(root, "No Message To Refile",
- "Please select a message to refile", "", 0, "OK")
- return
- foldersel = folderbox.curselection()
- if len(foldersel) != 1:
- if not foldersel:
- msg = "Please select a folder to refile to"
- else:
- msg = "Please select exactly one folder to refile to"
- dialog(root, "No Folder To Refile", msg, "", 0, "OK")
- return
- refileto = folderbox.get(foldersel[0])
- todo = []
- for i in sel:
- line = scanbox.get(i)
- if scanparser.match(line) >= 0:
- todo.append(string.atoi(scanparser.group(1)))
- if lastrefile != refileto or not tofolder:
- lastrefile = refileto
- tofolder = None
- tofolder = mh.openfolder(lastrefile)
- mhf.refilemessages(todo, tofolder)
- rescan()
- fixfocus(min(todo), itop)
-
- def fixfocus(near, itop):
- n = scanbox.size()
- for i in range(n):
- line = scanbox.get(`i`)
- if scanparser.match(line) >= 0:
- num = string.atoi(scanparser.group(1))
- if num >= near:
- break
- else:
- i = 'end'
- scanbox.select_from(i)
- scanbox.yview(itop)
-
- def setfolders():
- folderbox.delete(0, 'end')
- for fn in mh.listallfolders():
- folderbox.insert('end', fn)
-
- def rescan():
- global viewer
- if viewer:
- viewer.destroy()
- viewer = None
- scanbox.delete(0, 'end')
- for line in scanfolder(folder, seq):
- scanbox.insert('end', line)
-
- def scanfolder(folder = 'inbox', sequence = 'all'):
- return map(
- lambda line: line[:-1],
- os.popen('scan +%s %s' % (folder, sequence), 'r').readlines())
-
- main()
-